data = {
    biginpagehidden: false,
    score: 0,
    maxscore: 0,
    startx: 0,
    starty: 0,
    endx: 0,
    endy: 0,
    ground: [], //二维数组
    groundstatus: {}, //枚举类，枚举值为css样式变值
    rows: 20,
    cols: 18,
    snake: [], //数组的坐标列表，末尾为蛇头
    food: [], //当前食物坐标
    direction: "right", //实时方向
    timer: "", //setInterval函数返回值，用以停止
    speed: 300, //300ms走一格
    sensitivity: 30, //拖了10坐标就算确定输入
    stepturned: false, //防止一步掉头两次
    syspause: true, //时停，为了重置和暂停
    systemms: "开始", //开始 暂停 暂停中... 重新开始
    tipMs: "鼠标点击拖拽或点击按钮控制小蛇"
}

$(
    function() { onLoad() }
)

onLoad = function() {
    initMaxscore()
    initGround(data.rows, data.cols)
    initSnake()
    createFood()
    move() //setInterval
}

replay = function() {
    data.direction = "right"
    for (var i = 0; i < data.rows; i++) {
        for (var j = 0; j < data.cols; j++) {
            data.ground[i][j] = data.groundstatus.empty
            updateClass(i, j)
        }
    }
    data.ground[1][2] = data.groundstatus.snakehead[1]
    data.ground[1][1] = data.groundstatus.snaketail[1]
    updateClass(1, 2)
    updateClass(1, 1)
        //push顺序不能错，最后一个是头
    data.snake = [
        [1, 1],
        [1, 2]
    ]
    createFood()

    data.score = 0
    $(".scorenum").text(data.score)
    data.tipMs = "鼠标点击拖拽或点击按钮控制小蛇"
    $(".bigin_v_ms").text(data.tipMs)

}

initMaxscore = function() {
    //网页的cookie缓存可以有
    data.maxscore = 0
    $(".maxscorenum").text(data.maxscore)
}

initGround = function(rows, cols) {
    data.groundstatus = {
        empty: 0,
        snakehead: [11, 12, 13, 14], //上右下左
        snaketail: [21, 22, 23, 24], //上右下左
        food: [3, 4, 5, 6, 7, 8, 9],
        snakefoodbody: [32, 42, 52, 62, 72, 82, 92],
    }

    //二维数组初始化并把网页初始化
    //所有格子有class=block block_type_empty id=block_row_col
    for (var i = 0; i < rows; i++) {
        var arr = [];
        data.ground.push(arr);
        for (var j = 0; j < cols; j++) {
            data.ground[i].push(data.groundstatus.empty)
            $(".ground").append("<div class=\"block block_type_" + data.ground[i][j] + "\" id=\"block_" + i + "_" + j + "\"></div>")
        }
    }
}

initSnake = function() {
    data.ground[1][2] = data.groundstatus.snakehead[1]
    data.ground[1][1] = data.groundstatus.snaketail[1]

    updateClass(1, 2)
    updateClass(1, 1)

    //push顺序不能错，最后一个是头
    data.snake.push([1, 1])
    data.snake.push([1, 2])
}

//交互操作，移动方式为触摸然后拖动，不用放手也可
tapStart = function(e) {
    data.startx = e.pageX
    data.starty = e.pageY
}
tapMove = function(e) {
    if (e.buttons == 1)
        tapdetect(data.startx, data.starty, e.pageX, e.pageY)
}

clickdir = function(direction) {
    if (data.stepturned == true)
        return
    var nowDir = data.direction
    if (direction == "left" || direction == "right") {
        if (nowDir == "left" || nowDir == "right") {
            return;
        }
    } else if (direction == "top" || direction == "bottom") {
        if (nowDir == "top" || nowDir == "bottom") {
            return;
        }
    }
    changedbtncss1s(direction)
    data.stepturned = true
    data.direction = direction
}

presskey = function(e) {
    if (data.stepturned == true)
        return
    if (e.code == "KeyW") {
        clickdir("top")
    } else if (e.code == "KeyA") {
        clickdir("left")
    } else if (e.code == "KeyS") {
        clickdir("bottom")
    } else if (e.code == "KeyD") {
        clickdir("right")
    }
}

tapdetect = function(beginx, beginy, endx, endy) {
    var horizontal = endx - beginx
    var vertical = endy - beginy
    if ((Math.abs(horizontal) > data.sensitivity || Math.abs(vertical) > data.sensitivity) && data.stepturned == false) {
        var direction = figDir(horizontal, vertical)
        clickdir(direction)
        data.startx = endx
        data.starty = endy
    }
}

figDir = function(heng, zong) {
    var dirStr;
    if (Math.abs(heng) > Math.abs(zong)) {
        if (heng > 0) dirStr = "right"
        else dirStr = "left"
    } else {
        if (zong > 0) dirStr = "bottom"
        else dirStr = "top"
    }
    return dirStr
}

move = function() {
    data.timer = setInterval(function() {
        if (!data.syspause) {
            moveDir(data.direction)
        }
    }, data.speed)
}

moveDir = function(dir) {
        data.stepturned = false
        var snake = data.snake
        var len = data.snake.length
        var food = data.food
        var ground = data.ground
            //头将要在的坐标
        var sHeadwillbe = [snake[len - 1][0], snake[len - 1][1]]
        var headtype = 1
        if (dir == "left") {
            sHeadwillbe[1] -= 1
            headtype = 3
        } else if (dir == "right") {
            sHeadwillbe[1] += 1
            headtype = 1
        } else if (dir == "top") {
            sHeadwillbe[0] -= 1
            headtype = 0
        } else if (dir == "bottom") {
            sHeadwillbe[0] += 1
            headtype = 2
        }
        var frontstatus = judgefront(sHeadwillbe)
            //移动逻辑
        if (frontstatus == "open") {
            //snake的头是snake[len-1],尾是snake[0]
            //头到位
            ground[sHeadwillbe[0]][sHeadwillbe[1]] = data.groundstatus.snakehead[headtype]
            updateClass(sHeadwillbe[0], sHeadwillbe[1])
                //背景样式依次前挪，snake数组列表位置依次改变为前一个的
            for (var i = 0; i < len - 2; i++) {
                ground[snake[len - 1 - i][0]][snake[len - 1 - i][1]] = ground[snake[len - 2 - i][0]][snake[len - 2 - i][1]]
                updateClass(snake[len - 1 - i][0], snake[len - 1 - i][1])
            }
            var tailtype = 3
            ground[snake[0][0]][snake[0][1]] = data.groundstatus.empty
            updateClass(snake[0][0], snake[0][1])
            for (var i = 0; i < len - 1; i++) {
                snake[i] = snake[i + 1]
            }
            snake[len - 1] = sHeadwillbe
            if (snake[1][0] < snake[0][0]) tailtype = 0
            else if (snake[1][1] > snake[0][1]) tailtype = 1
            else if (snake[1][0] > snake[0][0]) tailtype = 2
            else if (snake[1][1] < snake[0][1]) tailtype = 3
            ground[snake[0][0]][snake[0][1]] = data.groundstatus.snaketail[tailtype]
            updateClass(snake[0][0], snake[0][1])
                //末尾成背景
        } else if (frontstatus == "eatfood") {
            //头与食物位置交换而已，其他不变
            var temp = ground[sHeadwillbe[0]][sHeadwillbe[1]]
            ground[sHeadwillbe[0]][sHeadwillbe[1]] = data.groundstatus.snakehead[headtype]
            updateClass(sHeadwillbe[0], sHeadwillbe[1])
                //数字3-9转化为0-6的index，得出的数字是32-92
            ground[snake[len - 1][0]][snake[len - 1][1]] = data.groundstatus.snakefoodbody[temp - 3]
            updateClass(snake[len - 1][0], snake[len - 1][1])
            snake.push(sHeadwillbe)
            data.score += 10
            $(".scorenum").text(data.score)
            StoreScore()
                //重新创建食物（自带删除)
            createFood()

        } else if (frontstatus == "outofrange" || frontstatus == "eatitself") {
            var ms = ""
            if (frontstatus == "outofrange") {
                ms = "超出边界"
            } else {
                ms = "吃到自己"
            }
            snakeOver(ms)
        }
    }
    //判断头将要碰到什么
judgefront = function(sHeadwillbe) {
        var frontstatus = "outofrange"
        if (sHeadwillbe[0] < 0 || sHeadwillbe[0] >= data.rows ||
            sHeadwillbe[1] < 0 || sHeadwillbe[1] >= data.cols) {
            frontstatus = "outofrange"
        } else if (data.ground[sHeadwillbe[0]][sHeadwillbe[1]] == data.groundstatus.empty) {
            frontstatus = "open"
        } else if (data.groundstatus.snakefoodbody.indexOf(data.ground[sHeadwillbe[0]][sHeadwillbe[1]]) != -1 || data.groundstatus.snaketail.indexOf(data.ground[sHeadwillbe[0]][sHeadwillbe[1]]) != -1) {
            frontstatus = "eatitself"
        } else if (data.groundstatus.food.indexOf(data.ground[sHeadwillbe[0]][sHeadwillbe[1]]) != -1) {
            frontstatus = "eatfood"
        }
        return frontstatus
    }
    //创建食物
createFood = function() {
    var ground = data.ground
    var randomArr = []
    for (var i = 0; i < data.rows; i++) {
        for (var j = 0; j < data.cols; j++) {
            if (ground[i][j] == data.groundstatus.empty) {
                randomArr.push([i, j])
            }
        }
    }
    var randomxy = randomArr[Math.floor(Math.random() * randomArr.length)]
    ground[randomxy[0]][randomxy[1]] = data.groundstatus.food[Math.floor(Math.random() * 7)] //0-6就是数字3-9

    updateClass(randomxy[0], randomxy[1])

    data.food = [randomxy[0], randomxy[1]]
}

//已绑定暂停按钮
snakefunc = function(btn) {
    var systemms = $(btn).text()
    var ms = ""
    var pause = false
    if (systemms == "暂停中...") {
        ms = "暂停"
        pause = false
    } else if (systemms == "暂停") {
        ms = "暂停中..."
        pause = true
    } else if (systemms == "开始") {
        ms = "暂停"
        pause = false

        biginpagehidden = true
        $(".bigin_v").prop("hidden", biginpagehidden)

    } else if (systemms == "重新开始") { //重新开始是回到按开始状态
        ms = "开始"
        pause = true
        replay()

        biginpagehidden = false
        $(".bigin_v").prop("hidden", biginpagehidden)
    }

    data.systemms = ms
    $(btn).text(ms)
    data.biginpagehidden = biginpagehidden
    data.syspause = pause
}

snakeOver = function(ms) {

    data.syspause = true
    data.tipMs = '游戏结束: ' + ms
    $(".bigin_v_ms").text(data.tipMs)
    data.biginpagehidden = false
    $(".bigin_v").prop("hidden", data.biginpagehidden)
    data.systemms = '重新开始'
    $(".pausebtn1").text(data.systemms)
}

//最大分计分器
StoreScore = function() {
    if (data.maxscore < data.score) {
        data.maxscore = data.score
        $(".maxscorenum").text(data.maxscore)
    }
}

updateClass = function(groundx, groundy) {
    $("#block_" + groundx + "_" + groundy).prop("class", "block block_type_" + data.ground[groundx][groundy])
}

changedbtncss1s = function(str) {
    $(".dbtn" + str).css("background-color", "rgb(224, 102, 102)")
    var timer = setTimeout(
        function() {
            $(".dbtn" + str).css("background-color", "rgb(255, 192, 192)")
        }, 200
    )
}